/*
 * main.cpp
 *
 *  Created on: Sep 18, 2011
 *      Author: thuvh
 */

#include <iostream>
#include <fstream>

#include <vector>

#include <cstring>

using namespace std;

vector<string> languages;
vector<string> typeOfFlies;
string programName;
string name;
string input;

/* -l en vn
 * -f file
 * -n [name of setid]
 * -h
 * example we have test.en and test.vn
 * --> -f test -l en vn -n hello
 * --> test-src.en.sgm, test-src.vn.sgm, test-ref.en.sgm and test-ref.vn.sgm
 *
 */

bool processFile(string inputFileName, string outputFileName,
		string typeOfFile, string name, string language, bool isRef = false);
void usage();
vector<string> split(string source, string delim = " ");

string ltrim(string source);
string rtrim(string source);
string trim(string source);

int main(int argc, char * argv[]) {
	typeOfFlies.push_back("ref");
	typeOfFlies.push_back("src");

	vector<string> tmp = split(argv[0], "/");
	programName = "PROGRAM";
	if (!tmp.empty()) {
		programName = tmp[tmp.size() - 1];
	}

	bool isHelp = false;
	//	bool isCheckParam = false;
	if (argc == 1) {
		usage();
		return 1;
	}

	for (int i = 1; i < argc; i++) {
		if (strcmp(argv[i], "-h") == 0) {
			//			usage();
			isHelp = true;
		} else if (strcmp(argv[i], "-n") == 0) {
			if (i == argc - 1) {
				usage();
				return 1;
			}
			name = argv[++i];
		} else if (strcmp(argv[i], "-l") == 0) {
			if (i == argc - 1 || i + 1 == argc - 1) {
				usage();
				return 1;
			}
			languages.push_back(argv[++i]);
			languages.push_back(argv[++i]);
		} else if (strcmp(argv[i], "-f") == 0) {
			if (i == argc - 1) {
				usage();
				return 1;
			}

			input = argv[++i];
		} else {
			isHelp = true;
		}
	}

	if (languages.size() != 2 || input.empty() || name.empty() || isHelp) {
		usage();
		return 1;
	}

	for (size_t ci = 0; ci < typeOfFlies.size(); ci++) {
		string typeOfFile = typeOfFlies[ci];
		bool isRef = false;
		if (typeOfFile.compare("ref") == 0) {
			isRef = true;
		}

		for (size_t cl = 0; cl < languages.size(); cl++) {
			string lang = languages[cl];

			string inputFile = input + "." + lang;
			string outputFile = input + "-" + typeOfFile + "." + lang + ".sgm";
			cout << "\tProcessing " << inputFile << " to " << outputFile
					<< endl;
			bool result = processFile(inputFile, outputFile, typeOfFile, name,
					lang, isRef);
			if (result) {
				cout << "\tDone.." << endl;
			}

		}
	}
	cout << "Finish!!!" << endl;
	return 0;
}

bool processFile(string inputFileName, string outputFileName,
		string typeOfFile, string name, string language, bool isRef) {
	ifstream fi(inputFileName.c_str());

	if (!fi.good()) {
		cout << "\t\terror when open " << inputFileName << endl;
		return false;
	}

	ofstream fo(outputFileName.c_str());

	//write header
	fo << "<" << typeOfFile << "set setid=\"" << name << "\" srclang=\"any\"";
	if (isRef) {
		fo << " trglang=\"" << language << "\"";
	}
	fo << ">" << endl;
	fo << "<doc docid=\"" << name << "\" genre=\"any\" origlang=\"any\"";

	if (isRef) {
		fo << " sysid=\"ref\"";
	}

	fo << ">" << endl;

	//write content
	bool isEndOfLine = false;
	long lineNumber = 0;
	while (true) {
		if (isEndOfLine) {
			break;
		}

		if (!fi.good()) {
			isEndOfLine = true;
		}

		string line;
		getline(fi, line, '\n');
		lineNumber++;
		//line = trim (line);

		if (line.empty()) {
			cout << "\t\tLine " << lineNumber << " is null" << endl;
			continue;
		}

		if (lineNumber % 1000000 == 0) {
			cout << lineNumber << "..." << endl;
		}
		fo << "<seg id=\"" << lineNumber << "\">" << line << "</seg>" << endl;
	}

	//write end of file
	fo << "</doc>" << endl;
	fo << "</" << typeOfFile << "set>" << endl;

	fi.close();
	fo.close();

	return true;
}

void usage() {
	cout << programName
			<< " [-h] -n <name> -f <file> -l <language1> <language2>" << endl;
	cout << "-h\t\t print help" << endl;
	cout << "-n <name>\t\t name of this set" << endl;
	cout << "-f <name>\t\t prefix of input file name" << endl;
	cout
			<< "-l <language 1> <language 2>\t\t pair of language need to be process"
			<< endl;
}

vector<string> split(string source, string delim) {
	vector<string> output;

	size_t bIdx = 0;

	while (bIdx < source.length()) {
		size_t eIdx = source.find_first_of(delim, bIdx);

		if (eIdx == string::npos) {
			eIdx = source.length();
		}

		string tmp = trim(source.substr(bIdx, eIdx - bIdx));

		if (!tmp.empty()) {
			output.push_back(tmp);
		}
		bIdx = eIdx + 1;
	}

	return output;
}

string ltrim(string source) {
	string tmp;

	if (!source.empty()) {
		size_t bIdx = 0;

		while (bIdx < source.length() && source[bIdx] == ' ') {
			bIdx++;
		}

		tmp = source.substr(bIdx);
	}
	return tmp;
}

string rtrim(string source) {
	string tmp;

	if (!source.empty()) {
		size_t eIdx = source.length() - 1;
		while (eIdx != string::npos && source[eIdx] == ' ') {
			eIdx--;
		}

		if (eIdx != string::npos) {
			tmp = source.substr(0, eIdx);
		}
	}

	return tmp;
}

string trim(string source) {
	return ltrim(rtrim(source));
}
